﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace DoVuiKinhThanh
{
    /// <summary>
    /// Represents a dynamic data collection that provides notifications when 
    /// view model items get added, removed, changed, or when the whole list is refreshed.
    /// </summary>
    /// <typeparam name="T">T: The type of view models in the collection.</typeparam>
    public class ViewModelObservableCollection<T> : ObservableCollection<T>
        where T : ViewModelBase
    {
        #region IEvents

        /// <summary>
        /// Raised when a property on a item of this collection has a new value.
        /// </summary>
        public event EventHandler<CollectionItemChangedEventArgs> ItemChanged;

        #endregion IEvents
        #region IMethods

        protected override void ClearItems()
        {
            foreach (T item in Items)
            {
                item.PropertyChanged -= ItemPropertyChanged;
            }

            base.ClearItems();
        }

        protected override void SetItem(int index, T item)
        {
            Items[index].PropertyChanged -= ItemPropertyChanged;

            base.SetItem(index, item);

            Items[index].PropertyChanged += ItemPropertyChanged;
        }

        protected override void RemoveItem(int index)
        {
            Items[index].PropertyChanged -= ItemPropertyChanged;

            base.RemoveItem(index);
        }

        protected override void InsertItem(int index, T item)
        {
            base.InsertItem(index, item);

            item.PropertyChanged += ItemPropertyChanged;
        }

        private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            var changedItem = sender as T;

            OnItemChanged(IndexOf(changedItem), e.PropertyName);
        }

        private void OnItemChanged(int index, string propertyName)
        {
            if (ItemChanged != null)
            {
                ItemChanged(this, new CollectionItemChangedEventArgs(index, propertyName));
            }
        }

        #endregion IMethods
    }
}